<

ページルート遷移をアニメーション化する

マテリアルなどの設計言語は、次の場合の標準的な動作を定義します。 ルート (または画面) 間の遷移。ただし、習慣として 画面間の遷移により、アプリをよりユニークにすることができます。助けるために、PageRouteBuilderを提供しますAnimation物体。 これAnimationと一緒に使用できますTweenCurveオブジェクトを使用してトランジション アニメーションをカスタマイズします。 このレシピでは、次の間を移行する方法を示します。 新しいルートをアニメーション化してルートを表示します。 画面の下部。

カスタム ページのルート遷移を作成するために、このレシピでは次の手順を使用します。

  1. PageRouteBuilder をセットアップする
  2. を作成しますTween
  3. を追加AnimatedWidget
  4. 使うCurveTween
  5. 2 つを組み合わせますTweens

1. PageRouteBuilder をセットアップする

開始するには、PageRouteBuilderを作成するRoutePageRouteBuilder2 つのコールバックがあり、1 つはルートのコンテンツを構築するためのものです (pageBuilder)、もう 1 つはルートのトランジションを構築するためのもの (transitionsBuilder)。

次の例では、2 つのルートを作成します。1 つは「Go!」の付いたホーム ルートです。ボタン、および 「ページ 2」というタイトルの 2 番目のルート。

import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Page1(),
    ),
  );
}

class Page1 extends StatelessWidget {
  const Page1({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.of(context).push(_createRoute());
          },
          child: const Text('Go!'),
        ),
      ),
    );
  }
}

Route _createRoute() {
  return PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      return child;
    },
  );
}

class Page2 extends StatelessWidget {
  const Page2({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: const Center(
        child: Text('Page 2'),
      ),
    );
  }
}

2.トゥイーンを作成する

新しいページを下からアニメーション化するには、次からアニメーション化する必要があります。Offset(0,1)Offset(0, 0)(通常は、Offset.zeroコンストラクタ)。この場合、オフセットは 2D ベクトルです。「分数翻訳」ウィジェット。 の設定dy1 の引数は垂直方向の平行移動を表します ページの高さ全体。

transitionsBuilderコールバックにはanimationパラメータ。それはAnimation<double>0 から 1 までの値を生成します。 アニメーションアニメーションにトゥイーンを使用して:

transitionsBuilder: (context, animation, secondaryAnimation, child) {
  const begin = Offset(0.0, 1.0);
  const end = Offset.zero;
  final tween = Tween(begin: begin, end: end);
  final offsetAnimation = animation.drive(tween);
  return child;
},

3. AnimatedWidget を使用する

Flutterには拡張されたウィジェットのセットがありますAnimatedWidgetアニメーションの値が変更されると、自動的に再構築されます。例えば、 SlideTransition はAnimation<Offset>そしてその子を翻訳します( FractionalTranslation ウィジェット)、アニメーションの値が変更されるたびに。

AnimatedWidget を返すSlideTransitionとともにAnimation<Offset>そして子ウィジェット:

transitionsBuilder: (context, animation, secondaryAnimation, child) {
  const begin = Offset(0.0, 1.0);
  const end = Offset.zero;
  final tween = Tween(begin: begin, end: end);
  final offsetAnimation = animation.drive(tween);

  return SlideTransition(
    position: offsetAnimation,
    child: child,
  );
},

4. CurveTween を使用する

Flutter は、イージング カーブの選択を提供します。 時間の経過に伴うアニメーションの速度を調整します。 のCurvesクラス は、よく使用される曲線の事前定義されたセットを提供します。 例えば、Curves.easeOutアニメーションを素早く開始し、ゆっくりと終了します。

カーブを使用するには、新しいカーブを作成しますCurveTweenそしてそれにCurveを渡します:

var curve = Curves.ease;
var curveTween = CurveTween(curve: curve);

この新しいトゥイーンは引き続き 0 から 1 までの値を生成します。次のステップでは、次のようになります。 を組み合わせたTween<Offset>ステップ2から。

5. 2 つのトゥイーンを結合します。

トゥイーンを組み合わせるには、 使用chain():

const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;

var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));

次に、このトゥイーンを次の関数に渡して使用します。animation.drive()。これにより、新しいものが作成されますAnimation<Offset>に与えることができるのはSlideTransitionウィジェット:

return SlideTransition(
  position: animation.drive(tween),
  child: child,
);

この新しいトゥイーン (またはアニメーション可能) は、Offset最初に評価して値を取得しますCurveTweenを評価し、Tween<Offset>.アニメーションが実行されると、 値は次の順序で計算されます。

  1. アニメーション (transitionsBuilder コールバックに提供される) は値を生成します 0から1へ。
  2. CurveTween は、その値に基づいて、これらの値を 0 と 1 の間の新しい値にマップします。 曲線。
  3. Tween<Offset>をマップしますdoubleに値するOffset価値観。

を作成する別の方法Animation<Offset>イージングカーブでは、CurvedAnimation:

transitionsBuilder: (context, animation, secondaryAnimation, child) {
  const begin = Offset(0.0, 1.0);
  const end = Offset.zero;
  const curve = Curves.ease;

  final tween = Tween(begin: begin, end: end);
  final curvedAnimation = CurvedAnimation(
    parent: animation,
    curve: curve,
  );

  return SlideTransition(
    position: tween.animate(curvedAnimation),
    child: child,
  );
}

インタラクティブな例

import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Page1(),
    ),
  );
}

class Page1 extends StatelessWidget {
  const Page1({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.of(context).push(_createRoute());
          },
          child: const Text('Go!'),
        ),
      ),
    );
  }
}

Route _createRoute() {
  return PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      const begin = Offset(0.0, 1.0);
      const end = Offset.zero;
      const curve = Curves.ease;

      var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));

      return SlideTransition(
        position: animation.drive(tween),
        child: child,
      );
    },
  );
}

class Page2 extends StatelessWidget {
  const Page2({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: const Center(
        child: Text('Page 2'),
      ),
    );
  }
}